﻿using S7.Net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace thinger.S7NetLib
{
    /// <summary>
    /// S7.net的二次封装(s7NetPlus这个框架不支持寻址V区，要映射到DB1，例如：V1要映射到DB1.DBX1.0)
    /// </summary>
    public class S7NetLib
    {
        /// <summary>
        /// （私有制段）西门子S7协议PLC通信类对象
        /// </summary>
        private Plc s7NetPlc = null;
        /// <summary>
        /// （公有属性）PLC的CPU类型
        /// </summary>
        public CpuType CPUType { get; set; }
        /// <summary>
        /// （公有属性）PLC的IP地址
        /// </summary>
        public string IPAddress { get; set; }
        /// <summary>
        /// (公有属性)PLC的机架号
        /// </summary>
        public short Rack { get; set; }
        /// <summary>
        /// (公有属性)PLC的插槽号
        /// </summary>
        public short Slot { get; set; }
        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="cpuType">PLC的CPU类型</param>
        /// <param name="ip">PLC的IP地址</param>
        /// <param name="rack">PLC的机架号</param>
        /// <param name="slot">PLC的插槽号</param>
        public S7NetLib(CpuType cpuType, string ip, short rack, short slot)
        {
            CPUType = cpuType;
            IPAddress = ip;
            Rack = rack;
            Slot = slot;
        }
        /// <summary>
        /// 打开PLC的连接
        /// </summary>
        public void OpenPLC()
        {
            //建立对象
            if (s7NetPlc == null)
            {
                s7NetPlc = new Plc(CPUType, IPAddress, Rack, Slot);
            }
            //判断PLC是否连接
            if (!s7NetPlc.IsConnected)
            {
                //设置读取延时
                s7NetPlc.ReadTimeout = 100;
                //设置写入延时
                s7NetPlc.WriteTimeout = 100;
                //打开
                s7NetPlc.Open();
            }
        }
        /// <summary>
        /// 关闭PLC连接
        /// </summary>
        public void ClosePCL()
        {
            if (s7NetPlc != null && s7NetPlc.IsConnected)
            {
                s7NetPlc.Close();
            }
        }
        /// <summary>
        /// 单个写入
        /// </summary>
        /// <param name="varAddress">地址（例如：DB1.DBX0.0）</param>
        /// <param name="varValue">值</param>
        public void WriteDataPLC(string varAddress, object varValue)
        {
            OpenPLC();
            lock (this)//规定加锁防止并发
            {
                this.s7NetPlc.Write(varAddress, varValue);
            }
        }
        /// <summary>
        /// PLC批量读取数据
        /// </summary>
        /// <param name="dataType">存储区类型</param>
        /// <param name="db">DB号</param>
        /// <param name="startByteAdr">开始的字节地址</param>
        /// <param name="count">读取的字节数量</param>
        /// <returns></returns>
        public byte[] ReadDataFromPLC(DataType dataType, int db, int startByteAdr, int count)
        {
            OpenPLC();
            lock (this)//加锁防止并发
            {
                byte[] bytes = this.s7NetPlc.ReadBytes(dataType, db, startByteAdr, count);
                return bytes;
            }
        }
    }
}
